<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8'>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>The LightWAVE Server Protocol</title>
<link rel="stylesheet" href="../css/lightwave.css">
</head>

<h2>The LightWAVE Server Protocol</h2>

<p>
LightWAVE is a lightweight waveform and annotation viewer and editor.  The
LightWAVE client runs within the user's web browser, communicating with the
LightWAVE server, <tt>lightwave</tt>, to obtain raw data that the client
formats and presents to the user.  This technical note describes the protocol
used for communicating with <tt>lightwave</tt>.  It will be of interest to
developers wishing to create custom clients and standalone applications that
make use of <tt>lightwave</tt>.

<p>
This note does not describe communications with the LightWAVE scribe
(<tt>lw-scribe</tt>), an independent server-side component that receives edit
logs uploaded by the LightWAVE client via standard HTTP file uploads.  These
logs are described in a separate note, <a href="edit-log.html">LightWAVE edit
logs</a>.

<p>
The LightWAVE server returns data
in <a href="http://www.json.org/">JSON/JSONP</a> format in response to
well-formed requests from any client (not limited to the standard LightWAVE
client). A public server is available at
<a href="http://physionet.org/cgi-bin/lightwave">http://physionet.org/cgi-bin/lightwave</a>;
it provides access to all of the 
<a href="http://physionet.org/faq.shtml#physiobank-formats">WFDB-compatible</a>
content in <a href="http://physionet.org/physiobank/database">PhysioBank</a>.

<p>
The C-language source code for the server is available from the 
<a href="https://physionet.org/works/LightWAVE">LightWAVE</a>
project on PhysioNetWorks (free registration and login required).  The
server can be installed as a
<a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI</a>
application on a web server such
as <a href="http://httpd.apache.org/">Apache</a>, or it can be run as a
command-line application.  For detailed instructions,
see <a href="server-install.html">Installing a local copy of the LightWAVE
server</a>.

<p>
Note that <tt>lightwave</tt> is not limited to serving data hosted by
the machine on which it's running, since it reads the data using
the <a href="http://physionet.org/physiotools/wfdb.shtml">WFDB
library</a>, allowing it to fetch data from other web servers as
needed.  A standard installation of <tt>lightwave</tt> retrieves data
from the server's local storage if available, or from PhysioNet otherwise.

<h3>Requests</h3>

<p>
When accessed via HTTP, requests are passed to <tt>lightwave</tt> in
<a href="http://en.wikipedia.org/wiki/Query_string">URL query
strings</a>, as for other CGI applications.  For example,
the <b><tt>dblist</tt></b> request can be sent to the public server by
opening
<pre>
    http://physionet.org/cgi-bin/lightwave?action=dblist
</pre>
with an HTTP client such as <tt>curl</tt>, <tt>wget</tt>, or any web browser.
More interesting examples appear below.

<p> To use <tt>lightwave</tt> as a command-line application, copy it into a
directory in your <a
href="http://en.wikipedia.org/wiki/PATH_%28variable%29">PATH</a>, then supply
an argument when you run it.  Any argument is acceptable, so these commands are
all equivalent:

<pre>
     lightwave -i
     lightwave hello
     lightwave I-want-a-pizza-to-go-with-no-anchovies
</pre>

In command-line mode, <tt>lightwave</tt> prompts for parameters as needed,
beginning with <b><tt>action</tt></b> (see below).  Type the value of each parameter,
ending your answer with a newline (press 'Enter').  For parameters that can
have multiple values (such as <b><tt>signal</tt></b>, see below) you will given
multiple prompts; enter one value at each prompt, and indicate the end of the
set of values by entering a newline only.

<p>
To use <tt>lightwave</tt> within a script, make an interactive test run and keep
track of what you need to type in response to <tt>lightwave</tt>'s prompts in
order to obtain the data your script will require.  Then create a plain text
file containing your responses in the correct order, and use your script to
supply the contents of this file to <tt>lightwave</tt> via its standard input;
see <tt>check/lw-test</tt> in the LightWAVE source package for an example.

<p>
<b>Parameters</b>

<p>
When interacting with <tt>lightwave</tt>, the <b><tt>action</tt></b> parameter
(see the next section) specifies the request type.  Depending on the
<b><tt>action</tt></b>, one or more of these parameters may be needed to specify the
data of interest:

<dl>
<dt><b><tt>db</tt></b></dt>
<dd>The (short form) name of the data collection (database), such as
<b><tt>edb</tt></b> (the short form name for the European ST-T Database).
Short form names of all of the PhysioBank databases are given in the
first column of
<a href="http://physionet.org/physiobank/database/DBS">http://physionet.org/physiobank/database/DBS</a>.
</dd>

<dt><b><tt>record</tt></b></dt>
<dd>The record name.</dd>

<dt><b><tt>signal</tt></b></dt>
<dd>A signal number or name (as displayed by the standard LightWAVE client).
Signals are numbered 0, 1, 2 ... in each record.</dd>

<dt><b><tt>annotator</tt></b></dt>
<dd>An annotator name.</dd>

<dt><b><tt>t0</tt></b></dt>
<dd>The starting time (the time interval from the beginning of the record to
the first sample or annotation of interest).  The value of this parameter can
be given in seconds, or as a string in H:M:S format.
Examples: 100 (1 minute 40 seconds); 30:25 (30 minutes 25 seconds); 10:15:20
(10 hours 15 minutes 20 seconds); 74:01:00 (3 days 2 hours 1 minute).</dd>

<dt><b><tt>dt</tt></b></dt>
<dd>The duration of the time interval of interest.  As for <b><tt>t0</tt></b>, this
parameter can be given in seconds or as a string.  Avoid specifying a duration
longer than 1 minute, however, when using the public <tt>lightwave</tt> server
to retrieve signals.</dd>
</dl>

<p>
In addition to these, the LightWAVE client passes a <b><tt>callback</tt></b> parameter
to the server (see <a href="#JSONP">JSONP</a> below).

<p>
<b>Request types</b>

<p>
The request type is passed as the value of <b><tt>action</tt></b>, and must be
one of:

<dl>
<dt><b><tt>dblist</tt></b></dt>
<dd>Get the list of databases (data collections).  Any other parameters
passed in the same request are ignored.
</dd>

<dt><b><tt>rlist</tt></b></dt>
<dd>Get the list of records within a database specified by the <b><tt>db</tt></b>
parameter.</dd>

<dt><b><tt>alist</tt></b></dt>
<dd>Get the list of annotators within a database specified by the <b><tt>db</tt></b>
parameter.</dd>

<dt><b><tt>info</tt></b></dt>
<dd>Get the metadata, including signal names, gains, and sampling
frequencies, for a record specified by the <b><tt>db</tt></b> and <b><tt>record</tt></b>
parameters.</dd>

<dt><b><tt>fetch</tt></b></dt> <dd>Retrieve data from a record specified by the
<b><tt>db</tt></b> and <b><tt>record</tt></b> parameters.  Specify the signal(s) and
annotator(s) of interest using the <b><tt>signal</tt></b> and
<b><tt>annotator</tt></b> parameters, and specify the time interval of
interest using the <b><tt>t0</tt></b> (starting time) parameter and the
<b><tt>dt</tt></b> (duration) parameter.

</dd>
</dl>

<b>Success or failure?</b>

<p>
Most responses from the LightWAVE server include a <b><tt>success</tt></b>
field, which is either <b><tt>true</tt></b> if the server was successful in
filling the request, or <b><tt>false</tt></b> otherwise.  In the latter case, an
additional field, <b><tt>error</tt></b>, has a string value that describes the
reason why the request could not be filled.

<p>
Since <b><tt>fetch</tt></b> requests can be partially successful, their
responses do not follow this pattern;  see the comments beneath the
<b><tt>fetch</tt></b> examples below for details.</p>

<b>Examples of requests</b>

<ul>

<li>To request the list of databases available via the public
<tt>lightwave</tt> server, use the URL

<pre>
    <a href="http://physionet.org/cgi-bin/lightwave?action=dblist">http://physionet.org/cgi-bin/lightwave?action=dblist</a>
</pre>
The server responds with
<pre>
{ "database": [
    { "name": "adfecgdb",
      "desc": "Abdominal and Direct Fetal ECG Database"
    },
    { "name": "aftdb",
      "desc": "AF Termination Challenge Database"
    },
    { "name": "aami-ec13",
      "desc": "ANSI/AAMI EC13 Test Waveforms"
    },
    <div style="color: blue"><em>... {more databases} ...</em></div>
    { "name": "ucddb",
      "desc": "UCD Sleep Apnea Database"
    },
    { "name": "mimic2db",
      "desc": "MIMIC II Waveform DB, v2 [deprecated, use v3]"
    },
    { "name": "mimic2db/numerics",
      "desc": "MIMIC II Waveform DB, v2 Numerics [deprecated, use v3]"
    }
  ],
  "version": "0.42",
  "success": true
}
</pre>
<p>The <b><tt>name</tt></b> fields are the short-format names that can be used as
values of the <b><tt>db</tt></b> parameter.</p>  The <b><tt>version</tt></b>
is the version number of the LightWAVE server, and it will vary.
<b><tt>success</tt></b> is either <b><tt>true</tt></b>, as shown, or
<b><tt>false</tt></b> if the server was unable to read the <b><tt>DBS</tt></b>
file (see the description of the <b><tt>db</tt></b> parameter above) in its
WFDB path (see the section on <em>Custom data repositories</em> in
<a href="server-install.html">Installing a local copy of the LightWAVE
server</a> for information about the WFDB path).</p>

<li> To request the list of records in the MIT-BIH Arrhythmia Database from the
public <tt>lightwave</tt> server, use the URL

<pre>
    <a href="http://physionet.org/cgi-bin/lightwave?action=rlist&db=mitdb">http://physionet.org/cgi-bin/lightwave?action=rlist&amp;db=mitdb</a>
</pre>
The server responds with
<pre>
{ "record": [
    "100",
    "101",
    <div style="color: blue"><em>... {more records} ...</em></div>
    "233",
    "234"
  ],
  "success": true
}
</pre>

<p><b><tt>success</tt></b> is either <b><tt>true</tt></b>, as shown, or
<b><tt>false</tt></b> if the server was unable to read
<b><tt>RECORDS</tt></b> from the directory specified by the value of
<b><tt>db</tt></b> (in this example, <b><tt>mitdb</tt></b>) in its WFDB
path.</p>

<li>To request the list of annotators in the QT Database from the public
<tt>lightwave</tt> server, use the URL

<pre>
    <a href="http://physionet.org/cgi-bin/lightwave?action=alist&db=qtdb">http://physionet.org/cgi-bin/lightwave?action=alist&amp;db=qtdb</a>
</pre>
The server responds with
<pre>
{ "annotator": [
    { "name": "atr",
      "desc": "reference beat annotations"
    },
    { "name": "man",
      "desc": "reference beat annotations for selected beats only"
    },
    <div style="color: blue"><em>... {more annotators} ...</em></div>
    { "name": "pu0",
      "desc": "automatically determined boundaries (based on signal 0 only)"
    },
    { "name": "pu1",
      "desc": "automatically determined boundaries (based on signal 1 only)"
    }
  ],
  "success": true
}
</pre>

<p>The <b><tt>name</tt></b> fields can be used as values of the <b><tt>annotator</tt></b> parameter. <b><tt>success</tt></b> is either <b><tt>true</tt></b>, as
shown, or <b><tt>false</tt></b> if the server was unable to read
<b><tt>ANNOTATORS</tt></b> from the directory specified by the value of
<b><tt>db</tt></b> (in this example, <b><tt>qtdb</tt></b>) in its WFDB
path.</p>

<li>To request the metadata for record <b><tt>slp67x</tt></b> of the MIT-BIH
Polysomnographic Database, use the URL

<pre>
    <a href="http://physionet.org/cgi-bin/lightwave?action=info&db=slpdb&record=slp67x">http://physionet.org/cgi-bin/lightwave?action=info&amp;db=slpdb&amp;record=slp67x</a>
</pre>
The server responds with
<pre>
{ "info":
  { "db": "slpdb",
    "record": "slp67x",
    "tfreq": 250,
    "start": "[01:06:00.000]",
    "end": "[02:23:00.000]",
    "duration": "1:17:00.000",
    "signal": [
      { "name": "ECG",
        "tps": 1,
        "units": null,
        "gain": 500,
        "adcres": 12,
        "adczero": 0,
        "baseline": 0
      },
      { "name": "BP",
        "tps": 1,
        "units": "mmHg",
        "gain": 7.72857,
        "adcres": 12,
        "adczero": 0,
        "baseline": -1147
      },
    <div style="color: blue"><em>... {more signals} ...</em></div>
      { "name": "SO2",
        "tps": 1,
        "units": "%",
        "gain": 17.5,
        "adcres": 12,
        "adczero": 0,
        "baseline": -808
      }
    ],
    "note": [
      " x M x 24-01-90"
    ]
  },
  "success": true
}
</pre>

<p>The <b><tt>treq</tt></b> field indicates the number of clock ticks per second,
which is the least common multiple of the sampling frequency of the signals
included in the record.  In most records, all signals are sampled at
<b><tt>tfreq</tt></b>, and the <b><tt>tps</tt></b> (ticks per sample) field is 1 for each
signal.  In multifrequency records, including most EDF-format records, one or
more signals is sampled at a lower frequency, and <b><tt>tps</tt></b> is greater than
1 for these signals.</p>

<p>If the <b><tt>start</tt></b> and <b><tt>end</tt></b> times are bracketed, as in the example
above, they indicate the times of day when the recording began and ended.  For
many recordings, this information is unavailable, and in such cases
<b><tt>start</tt></b> and <b><tt>end</tt></b> are <b><tt>null</tt></b>.</p>

<p>The <b><tt>units</tt></b> field is a string that indicates the physical units of
the signal, if known (or <b><tt>null</tt></b> if unknown).  The <b><tt>base</tt></b> is the
value (in raw units) that corresponds to 0 physical units, and the <b><tt>gain</tt></b>
is the number of raw units per physical units.  (See the next example.)

<p>The <b><tt>adcres</tt></b> and <b><tt>adczero</tt></b> fields specify the number of significant bits per sample (the analog-to-digital converter resolution) and the
center of the range (typically zero except for offset binary converters).

<p>The <b><tt>note</tt></b> field may be <b><tt>null</tt></b> if there are no
notes ("info" strings) for the selected record, or it may contain one or more
strings, as in this example.  See the home page for the database for information
about interpreting the notes.  In this case, the note indicates that the subject
was male ("M"), for example;  often notes contain other useful information
about the subject, such as age, diagnoses, and medications.

<p><b><tt>success</tt></b> is either <b><tt>true</tt></b>, as
shown, or <b><tt>false</tt></b> if the server was unable to read
the <tt>.hea</tt> (or EDF/EDF+) file for the specified record.</p>

<li>To request samples of signals 0 and 1, and annotations from annotators
<b><tt>ecg</tt></b> and <b><tt>st</tt></b> from record slp67x of the MIT-BIH Polysomnographic
Database, for a 10-second interval starting 15 minutes after the beginning of the record, use the URL

<pre>
    <a href="http://physionet.org/cgi-bin/lightwave?action=fetch&db=slpdb&record=slp67x&signal=0&signal=1&annotator=ecg&annotator=st&t0=15:0&dt=10">http://physionet.org/cgi-bin/lightwave?action=fetch&amp;db=slpdb&amp;record=slp67x&amp;signal=0&amp;signal=1&amp;annotator=ecg&amp;annotator=st&amp;t0=15:0&amp;dt=10</a>
</pre>
The server responds with
<pre>
{ "fetch":
  { "signal":
    [
      { "name": "ECG",
        "units": "mV [assumed]",
        "t0": 225000,
        "tf": 227500,
        "gain": 500,
        "base": 0,
        "tps": 1,
        "scale": 1,
        "samp": [ -20,2,4,-6,1,5 <span style="color: blue"><em>... {more samples} ...</em></span> 0,0,-1 ]
      },
      { "name": "BP",
        "units": "mmHg",
        "t0": 225000,
        "tf": 227500,
        "gain": 7.72857,
        "base": -1147,
        "tps": 1,
        "scale": 100,
        "samp": [ -515,0,0,1,0,-2 <span style="color: blue"><em>... {more samples} ...</em></span> -9,-11,-12 ]
      }
    ],
    "annotator":
    [
      { "name": "ecg",
        "annotation":
        [
          { "t": 225051,
            "a": "N",
            "s": 0,
            "c": 0,
            "n": 0,
            "x": null
          },
          { "t": 225226,
            "a": "N",
            "s": 0,
            "c": 0,
            "n": 0,
            "x": null
          },
          <em style="color: blue">... {more annotations} ...</em>
          { "t": 227399,
            "a": "N",
            "s": 0,
            "c": 0,
            "n": 0,
            "x": null
          }
        ]
      },
      { "name": "st",
        "annotation":
        [
          { "t": 225000,
            "a": "\"",
            "s": 0,
            "c": 0,
            "n": 0,
            "x": "W"
          }
        ]
      }
    ]
  }
}
</pre>

<p>Note that signals can be requested by number (as above) or by name;  thus
the request

<pre>
    <a href="http://physionet.org/cgi-bin/lightwave?action=fetch&db=slpdb&record=slp67x&signal=ECG&signal=BP&annotator=ecg&annotator=st&t0=15:0&dt=10">http://physionet.org/cgi-bin/lightwave?action=fetch&amp;db=slpdb&amp;record=slp67x&amp;<b>signal=ECG&amp;signal=BP</b>&amp;annotator=ecg&amp;annotator=st&amp;t0=15:0&amp;dt=10</a>
</pre>

is equivalent to the previous request, and the response from the server is
the same.

<p>The arrays of <b><tt>signal</tt></b> and <b><tt>annotator</tt></b> objects will be
omitted if no signals or annotators are requested.

<p>In the <b><tt>signal</tt></b> objects, the <b><tt>name</tt></b>, <b><tt>units</tt></b>,
<b><tt>gain</tt></b>, <b><tt>base</tt></b>, and <b><tt>tps</tt></b> fields are as described in the
previous example.  The <b><tt>t0</tt></b> and <b><tt>tf</tt></b> fields indicate the sequence
number of the first sample in the <b><tt>samp</tt></b> array and the sequence number
of the sample that follows the last sample in the array; sequence numbers begin
with 0.  The <b><tt>scale</tt></b> field indicates the conventional display scale for
the signal in physical units per cm.  The first element of each <b><tt>samp</tt></b>
array is the amplitude of sample <b><tt>t0</tt></b> of the signal in raw units; the
remaining elements are the first differences (i.e., the amplitude of sample
<b><tt>t0</tt></b>+<em>n</em> is the sum of the first <em>n+1</em> elements).

<blockquote> <em>In the example above, the first few elements of the second
<b><tt>samp</tt></b> array are -515, 0, 0, 1, 0, and -2.  The reconstructed raw samples
are -515, -515, -515, -514, -514, and -516.  To convert these raw
amplitudes into arterial blood pressure ("ART") measurements in physical units
("mmHg"), subtract the <b><tt>base</tt></b> (-1147) and divide by the <b><tt>gain</tt></b>
(7.72857) to get 81.775 ([(-512)-(-1147)]*7.72857), 81.775, 81.775, 81.904,
81.904, and 81.645.

<p>To determine the times of these samples, first note that the requested start
time (15 minutes following the start of the record) matches <b><tt>t0</tt></b>
(225000), and that <b><tt>tps</tt></b> is 1 for the BP signal (as it is for the other
signals); thus the sampling frequency of the BP signal is 225000/(15*60), or
250 samples per second, and the times of the six samples are 15:00, 15:00.004,
15:00.008, 15:00.012, 15:00.016, and 15:00.020.</em> </blockquote>

<p>Although passing samples as first differences in raw amplitude units
requires a modest amount of computation by the client to convert to physical
units, difference data in (integer) raw units can be transmitted 2 to 5 times
faster than data in scaled units and, more significantly, this method does not
introduce floating-point errors that may accumulate in client-side digital
signal processing such as filtering and power spectral analysis.

<p> In the <b><tt>annotator</tt></b> objects, the <b><tt>name</tt></b> field specifies the
annotator name, and the <b><tt>annotation</tt></b> array contains the individual
annotations associated with that annotator.  In the annotations,
the <b><tt>t</tt></b>, <b><tt>a</tt></b>, <b><tt>s</tt></b>, <b><tt>c</tt></b>, <b><tt>n</tt></b>, and <b><tt>x</tt></b>
fields are the time, annotation type (mnemonic), subtype, "chan", "num", and
"aux" fields of the WFDB annotation structures.  See the section
titled <em>Annotation Structures</em> in
the <a href="http://physionet.org/physiotools/wpg/">WFDB Programmer's Guide</a>
for definitions of these fields.  The standard annotation type mnemonics are
defined
in <a href="http://physionet.org/physiobank/annotations.shtml">PhysioBank
Annotations</a>;  non-standard types are described on the home pages of the
databases in which they are found.

<blockquote><em>In the example above, the three annotations belonging to
annotator <b><tt>ecg</tt></b> are all of type '<b><tt>N</tt></b>', representing normal QRS
complexes in the ECG.  The home page for the MIT-BIH Polysomnographic Database
notes that annotator <b><tt>st</tt></b> contains sleep stage annotations of type
'<b><tt>"</tt></b>' (in JSON notation, shown as <b><tt>"\""</tt></b>), with a sleep stage
mnemonic in the <b><tt>x</tt></b> field (<b><tt>W</tt></b> in the example, signifying
wakefulness).</em></blockquote>

<p>As a special case, if <b><tt>t0</tt></b> and <b><tt>dt</tt></b> are 0, the server returns
all annotations for the requested annotators, and no samples for any requested
signals.

<p>Unlike the other request types, the response to <b><tt>fetch</tt></b> does
not include a <b><tt>success</tt></b> field.  If the server was unable to
obtain requested signal data, <b><tt>fetch.signal</tt></b> is an empty array;
similarly <b><tt>fetch.annotator</tt></b> is an empty array if none of the
requested annotations were read.  If no signals were requested,
<b><tt>fetch.signal</tt></b> is omitted from the response, and if no annotations
were requested, <b><tt>fetch.annotator</tt></b> is likewise omitted.  If neither
signals nor annotations were requested, the server returns
<pre>
{ "fetch": null }
</pre>

</ul>

<a name="JSONP"><h3>JSONP</h3></a>

<p>
The LightWAVE server looks in its parameter list for a <b><tt>callback</tt></b>
parameter.  If present, the server takes the value of <b><tt>callback</tt></b>
as the name of a function, and "wraps" its JSON output within an invocation
of the function.  Thus, if the value of <b><tt>callback</tt></b> were <b><tt>foo</tt></b>,
the output would appear as
<pre>
foo(<em style="color: blue">... {JSON output} ...</em>)
</pre>
This form of output is called JSONP, and it is supported so that clients
hosted on other machines can interact with the LightWAVE server.  Such
cross-domain communication would otherwise be disallowed by modern browsers.
See <a href="client-install.html">Installing a local copy of the LightWAVE
client</a> for information about setting up a testbed for development and
customization without the overhead of running a local web server.
</html>
